package cn.mcsys.platform.core.service;

import cn.mcsys.myadmin.common.utils.DateUtils;
import cn.mcsys.myadmin.common.utils.HttpRequestUtil;
import cn.mcsys.myadmin.dubbo.service.BackService;
import cn.mcsys.myadmin.modules.air.entity.AirCar;
import cn.mcsys.myadmin.modules.air.entity.AirCarRecord;
import cn.mcsys.myadmin.modules.air.entity.AirRidePoint;
import cn.mcsys.myadmin.modules.air.entity.AirRideQrCodeSpecial;
import cn.mcsys.myadmin.modules.platform.entity.AirVehicleGpsBus;
import cn.mcsys.myadmin.modules.viewer.entity.AirRideQrCode;
import cn.mcsys.myadmin.modules.worker.entity.AirTaxi;
import cn.mcsys.platform.core.entity.AirRidePointDto;
import cn.mcsys.platform.core.entity.PointVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * @author bobo
 * @create 2018-09-29 16:11
 * @desc ${DESCRIPTION}
 **/
@Service
public class PlatformService {

    private static String[] time_gap = new String[]{
            "00:00-00:30", "00:30-01:00", "01:00-01:30", "01:30-02:00", "02:00-02:30", "02:30-03:00",
            "03:00-03:30", "03:30-04:00", "04:00-04:30", "04:30-05:00", "05:00-05:30", "05:30-06:00",
            "06:00-06:30", "06:30-07:00", "07:00-07:30", "07:30-08:00", "08:00-08:30", "08:30-09:00",
            "09:00-09:30", "09:30-10:00", "10:00-10:30", "10:30-11:00", "11:00-11:30", "11:30-12:00",
            "12:00-12:30", "12:30-13:00", "13:00-13:30", "13:30-14:00", "14:00-14:30", "14:30-15:00",
            "15:00-15:30", "15:30-16:00", "16:00-16:30", "16:30-17:00", "17:00-17:30", "17:30-18:00",
            "18:00-18:30", "18:30-19:00", "19:00-19:30", "19:30-20:00", "20:00-20:30", "20:30-21:00",
            "21:00-21:30", "21:30-22:00", "22:00-22:30", "22:30-23:00", "23:00-23:30", "23:30-24:00"};

    @Autowired
    private BackService backService;

    /**
     * @return 获取DtoListMap
     */
    public Map<String, Object> getRidePointDtoListMap() {
        Map<String, Object> result = new HashMap<>();
        result.put("airRidePointDtoList", getRidePointDtoList());
        return result;
    }

    /**
     * @return 获取DtoList
     */
    public List<AirRidePointDto> getRidePointDtoList() {
        List<AirRidePoint> airRidePointList = backService.selectAllPoint2();
        List<AirRidePointDto> airRidePointDtos = getAirRidePointDtos(airRidePointList);
        return airRidePointDtos;
    }

    /**
     * @return 获取DtoList2
     */
    public List<AirRidePointDto> getRidePointDtoList2() {
        List<AirRidePoint> airRidePointList = backService.selectAllPoint2();
        List<AirRidePointDto> airRidePointDtos = new ArrayList<>();
        for (AirRidePoint airRidePoint : airRidePointList) {
            AirRidePointDto airRidePointDto = getDto2(airRidePoint);
            airRidePointDtos.add(airRidePointDto);
        }
        return airRidePointDtos;
    }

    private List<AirRidePointDto> getAirRidePointDtos(List<AirRidePoint> airRidePoints) {
        List<AirRidePointDto> airRidePointDtos = new ArrayList<>();
        for (AirRidePoint airRidePoint : airRidePoints) {
            AirRidePointDto airRidePointDto = getDto(airRidePoint);
            airRidePointDtos.add(airRidePointDto);
        }
        return airRidePointDtos;
    }

    /**
     * 乘车点概况chart2 专线柱状图
     *
     * @param airRidePointId
     * @return
     */
    public Map<String, Object> getRidePointBarData(Integer airRidePointId) {
        Map<String, Object> result = new HashMap<>();
        result.put("airCarRecordList", getRidePointBarMap(airRidePointId));
        result.put("airRidePointDtoList", getRidePointDtoList());
        return result;
    }

    public Map<String, List<AirCarRecord>> getRidePointBarMap(Integer airRidePointId) {
        Map<String, List<AirCarRecord>> map = new HashMap<>();
        for (int i = 0; i < time_gap.length; i++) {
            List<AirCarRecord> airCarRecords = new ArrayList<>();
            map.put(time_gap[i], airCarRecords);
        }
        List<AirCarRecord> airCarRecordToday = backService.getAirCarRecordToday();
        if (airRidePointId == null || airRidePointId == 0 || airRidePointId == -1) {//所有乘车点
            for (AirCarRecord record : airCarRecordToday) {
                if (record.getStatus() == 2) {
                    String formatDate = DateUtils.formatDate(record.getRecordDate(), "HH:mm");
                    String[] split = formatDate.split(":");
                    int index = 2 * (Integer.parseInt(split[0])) + (Integer.parseInt(split[1]) < 30 ? 0 : 1);
                    if (index >= 0 && index < time_gap.length) {
                        List<AirCarRecord> airCarRecords = map.get(time_gap[index]);
                        airCarRecords.add(record);
                        map.put(time_gap[index], airCarRecords);
                    }
                }
            }
        } else {
            for (AirCarRecord record : airCarRecordToday) {
                if (record.getAirCar() != null) {
                    if (record.getStatus() == 2) {
                        if (record.getAirCar().getAirRidePoint().getId() == airRidePointId) {
                            String formatDate = DateUtils.formatDate(record.getRecordDate(), "HH:mm");
                            String[] split = formatDate.split(":");
                            int index = 2 * (Integer.parseInt(split[0])) + (Integer.parseInt(split[1]) < 30 ? 0 : 1);
                            if (index >= 0 && index < time_gap.length) {
                                List<AirCarRecord> airCarRecords = map.get(time_gap[index]);
                                airCarRecords.add(record);
                                map.put(time_gap[index], airCarRecords);
                            }
                        }
                    }
                }
            }
        }
        return map;
    }

    /*
    public void fillWithSpecialCode(Map<String, List<AirCarRecord>> map, List<AirRideQrCodeSpecial> pointQrCodeSpecial) {
        for (AirRideQrCodeSpecial record : pointQrCodeSpecial) {
            String formatDate = DateUtils.formatDate(record.getCreateDate(), "HH:mm");
            String[] split = formatDate.split(":");
            int index = 2 * (Integer.parseInt(split[0])) + (Integer.parseInt(split[1]) < 30 ? 0 : 1);
            if (index >= 0 && index < time_gap.length) {
                List<AirCarRecord> airCarRecords = map.get(time_gap[index]);
                if(airCarRecords.size()>0) {
                    airCarRecords.get(0).setPassengerSum(airCarRecords.get(0).getPassengerSum() + record.getRideNo());
                }else {
                    AirCarRecord a = new AirCarRecord();
                    a.setPassengerSum(record.getRideNo());
                    airCarRecords.add(a);
                }
                map.put(time_gap[index], airCarRecords);
            }
        }
    }*/

    /*
    public List<AirCarRecord> getRecordData(Integer airRidePointId) {
        String formatDate = DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:00:00");
        System.out.println(formatDate);
        List<AirCarRecord> airCarRecordList = backService.getAirCarRecordInTime(formatDate, airRidePointId);
        return airCarRecordList;
    }
    */

    /**
     * 乘车点table 即将返程|平均耗时
     *
     * @param airRidePointId
     * @return
     */
    public Map<String, Object> getAvgConsume(Integer airRidePointId) {
        Map<String, Object> result = new HashMap();

        Map<String, Object> map = new HashMap();
        map.put("key", "d227e19b929ec1d67ce90688d38d9dea");
        map.put("type", "1");
        String url = "https://restapi.amap.com/v3/distance";

        AirRidePoint airRidePoint = backService.selectPointById(airRidePointId);
        int back_time = 0, go_time = 0;
        try {
            String origins = airRidePoint.getLon() + "," + airRidePoint.getLat();
            String destination = airRidePoint.getAirParkingLot().getLon() + "," + airRidePoint.getAirParkingLot().getLat();
            map.put("origins", origins);
            map.put("destination", destination);
            String httpGet = HttpRequestUtil.httpGet(url, map);
            JSONObject jsonObject1 = JSON.parseObject(httpGet);
            String infocode1 = (String) jsonObject1.get("infocode");
            if ("10000".equals(infocode1)) {
                JSONArray results = jsonObject1.getJSONArray("results");
                String duration = (String) results.getJSONObject(0).get("duration");
                go_time = Integer.parseInt(duration) / 60;
            }
            map.put("origins", destination);
            map.put("destination", origins);
            httpGet = HttpRequestUtil.httpGet(url, map);
            JSONObject jsonObject2 = JSON.parseObject(httpGet);
            String infocode2 = (String) jsonObject2.get("infocode");
            if ("10000".equals(infocode2)) {
                JSONArray results = jsonObject2.getJSONArray("results");
                String duration = (String) results.getJSONObject(0).get("duration");
                back_time = Integer.parseInt(duration) / 60;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        List<AirCar> airCarList = backService.getCarByStatusAndAirRidePointId(4, airRidePointId);
        int seconds = 60 * (60 - DateUtils.getMinutes());

        List<AirCar> backing = new ArrayList<>();
        List<AirCar> backing_next = new ArrayList<>();

        for (AirCar airCar : airCarList) {
            try {
                String origins = airCar.getLon() + "," + airCar.getLat();
                String destination = airCar.getAirRidePoint().getAirParkingLot().getLon() + "," + airCar.getAirRidePoint().getAirParkingLot().getLat();
                map.put("origins", origins);
                map.put("destination", destination);
                String httpGet = HttpRequestUtil.httpGet(url, map);
                JSONObject jsonObject = JSON.parseObject(httpGet);
                String infocode = (String) jsonObject.get("infocode");
                if ("10000".equals(infocode)) {
                    JSONArray results = jsonObject.getJSONArray("results");
                    String duration = (String) results.getJSONObject(0).get("duration");
                    if (Long.parseLong(duration) < seconds) {
                        backing.add(airCar);
                    } else if (Long.parseLong(duration) < 3600 + seconds) {
                        backing_next.add(airCar);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        result.put("go_time", go_time);
        result.put("back_time", back_time);
        result.put("backing", backing);
        result.put("backing_next", backing_next);
        return result;
    }

    /**
     * 乘车点table 前一趟耗时
     *
     * @param airRidePointId
     * @return
     */
    public Map<String, Object> getLeastConsume(Integer airRidePointId) {
        Map<String, Object> result = new HashMap<>();
        getLeastTimeRecord(airRidePointId, result);
        return result;
    }

    private void getLeastTimeRecord(Integer airRidePointId, Map<String, Object> result) {
        int least_go_time = 0, least_back_time = 0;

        List<AirCarRecord> leastArrivedRecord = backService.getLeastRecordByStatusAndPointId(airRidePointId, 3);
        if (leastArrivedRecord != null) {
            if (leastArrivedRecord.size() > 0) {
                AirCarRecord arrivedRecord = leastArrivedRecord.get(0);
                AirCarRecord goRecord = backService.selectLatestCarRecordWithDate(arrivedRecord.getAirCar(), 2, arrivedRecord.getRecordDate());
                if (goRecord != null) {
                    least_go_time = (int) DateUtils.getDistanceMinutesOfTwoDate(goRecord.getRecordDate(), arrivedRecord.getRecordDate());
                }
            }
        }
        List<AirCarRecord> leastBackRecord = backService.getLeastRecordByStatusAndPointId(airRidePointId, 1);
        if (leastBackRecord != null) {
            if (leastBackRecord.size() > 0) {
                AirCarRecord backRecord = leastBackRecord.get(0);
                AirCarRecord startBackRecord = backService.selectLatestCarRecordWithDate(backRecord.getAirCar(), 4, backRecord.getRecordDate());
                if (startBackRecord != null) {
                    least_back_time = (int) DateUtils.getDistanceMinutesOfTwoDate(startBackRecord.getRecordDate(), backRecord.getRecordDate());
                }
            }
        }
        result.put("least_go_time", least_go_time);
        result.put("least_back_time", least_back_time);
    }

    /*
    public List<AirCarRecord> getAirCarRecordLeast() {
        List<AirCarRecord> airCarRecordLeast = backService.getAirCarRecordLeast();
        return airCarRecordLeast;
    }*/

    public Object getGps() {
        Map<String, Object> result = new HashMap<>();
        Date date = new Date();
        List<AirCar> specialList = backService.getAllCarsHavingGPS();
        List<AirVehicleGpsBus> busList = backService.getBusGps(date, date);
        List<AirVehicleGpsBus> turnBusList = backService.getBusByNote("chuanshu");
        List<AirVehicleGpsBus> boBusList = backService.getBusByNote("jiebo");
        List<AirVehicleGpsBus> travelBusList = backService.getBusByNote("travel");
        List<AirTaxi> taxiList = backService.select20sGPS(date, date);

        result.put("specialList", specialList);
        result.put("busList", busList);
        result.put("turnBusList", turnBusList);
        result.put("boBusList", boBusList);
        result.put("travelBusList", travelBusList);
        result.put("taxiList", taxiList);

        return result;
    }



    /**
     * 乘车点table 候车人数|预约人数|已运送人数
     *
     * @param airRidePointId
     * @return
     */
    public Map<String, Object> getTableData(Integer airRidePointId) {
        Map<String, Object> result = new HashMap<>();
        AirRidePoint airRidePoint = backService.selectPointById(airRidePointId);
        AirRidePointDto dto = getDto(airRidePoint);
        result.put("dto", dto);
        return result;
    }

    private AirRidePointDto getDto(AirRidePoint airRidePoint) {
        AirRidePointDto airRidePointDto = new AirRidePointDto();
        airRidePointDto.setAirRidePoint(airRidePoint);
        //todo fake
        //预约人数
        String date = DateUtils.getDate("yyyy-MM-dd");
        Integer appointSum = backService.selectCountByPointId(airRidePoint.getId(),"2018-11-09");
        if(appointSum==null){
            appointSum = 0;
        }

        //运力
        int takerSum = 0;
        List<AirCar> carList = backService.selectByPointId(airRidePoint.getId());
//        List<AirCar> carList = backService.getCarByStatusAndAirRidePointId(1, airRidePoint.getId());
        takerSum = getTakerSum(takerSum, carList);
        airRidePointDto.setCarList(carList);
        airRidePointDto.setWorkerList(backService.getWorkersByRidePointId(airRidePoint.getId()));

        //已运送人数
        int tookSum = 0;
        List<AirCarRecord> recordList = backService.getRecordTodayByPointId(airRidePoint.getId());
        for (AirCarRecord record : recordList) {
            if(record.getPassengerSum()!=null) {
                if (record.getStatus() == 2) {
                    tookSum += record.getPassengerSum();
                }
            }
        }

        airRidePointDto.setTakerSum(takerSum);
        airRidePointDto.setAppointSum(appointSum);
        airRidePointDto.setTookSum(tookSum);
        return airRidePointDto;
    }

    private int getTakerSum(int takerSum, List<AirCar> carList) {
        for (AirCar car : carList) {
            if (car.getStatus() != null) {
                if(car.getSeating()!=null) {
                    if (car.getStatus() == 1) {
                        takerSum += car.getSeating();
                    }
                }
            }
        }
        return takerSum;
    }

    private AirRidePointDto getDto2(AirRidePoint airRidePoint) {
        AirRidePointDto airRidePointDto = new AirRidePointDto();
        airRidePointDto.setAirRidePoint(airRidePoint);
        //todo fake
        //预约人数
        String date = DateUtils.getDate("yyyy-MM-dd");
        Integer appointSum = backService.selectCountByPointId(airRidePoint.getId(),"2018-11-09");
        if(appointSum==null){
            appointSum = 0;
        }

        //运力
        int takerSum = 0;
        List<AirCar> carList = backService.selectByPointId(airRidePoint.getId());
        takerSum = getTakerSum(takerSum, carList);
        airRidePointDto.setCarList(carList);
        airRidePointDto.setWorkerList(backService.getWorkersByRidePointId(airRidePoint.getId()));

        //已乘车人数
        int tookSum = 0;
        //todo  二维码
        List<AirRideQrCode> qrCodeList = backService.selectByDate("2018-11-09");
        if(qrCodeList!=null) {
            for (AirRideQrCode code : qrCodeList) {
                if(code.getAirRidePoint()!=null) {
                    if (code.getAirRidePoint().getId().equals(airRidePoint.getId())) {
                        tookSum += code.getRideNo();
                    }
                }
            }
        }
        // TODO 通用二维码
        List<AirRideQrCodeSpecial> specialList = backService.getAllQrCodeSpecialByDate(String.valueOf(airRidePoint.getId()),"2018-11-09");
        if(specialList!=null) {
            for (AirRideQrCodeSpecial special : specialList) {
                tookSum += special.getRideNo();
            }
        }

        airRidePointDto.setTakerSum(takerSum);
        airRidePointDto.setAppointSum(appointSum);
        airRidePointDto.setTookSum(tookSum);
        return airRidePointDto;
    }

    public Map<String, Object> getMoveChartData() {
        Map<String, Object> result = new HashMap<>();
        //ZHData  市内
        List<PointVO> in = new ArrayList<>();
        //市外
        List<PointVO> out = new ArrayList<>();
        //geoCoordMap 地理位置
//        Map<String, Object> geoCoordMap = new HashMap<>();
        List<AirRidePoint> ridePointList = backService.selectAllPoint2();
        for (AirRidePoint airRidePoint : ridePointList) {
            PointVO pointVO = getAirRidePointVO(airRidePoint);
            in.add(pointVO);

            PointVO vo = new PointVO();
//            PointVO geoVo = new PointVO();
            try {
                BeanUtils.copyProperties(vo, pointVO);
//                BeanUtils.copyProperties(geoVo,pointVO);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            out.add(vo);
//            geoCoordMap.put(geoVo.getName(),geoVo);
        }
        //CCData 所有乘车点
        List<AirRidePoint> outPointList = backService.selectOutSidePoint();
        Map<String, PointVO> cityMap = new HashMap<>();
        for (AirRidePoint point : outPointList) {
            PointVO pointVO = getAirRidePointVO(point);
            out.add(pointVO);


//            PointVO geoVo = new PointVO();
//            geoVo.setName(point.getName());
//            geoVo.setLon(point.getLon());
//            geoVo.setLat(point.getLat());
//            geoCoordMap.put(geoVo.getName(),geoVo);
            PointVO cityVo = cityMap.get(point.getCity());
            if (cityVo == null) {
                PointVO vo = new PointVO();
                vo.setCarSum(pointVO.getCarSum());
                vo.setSeatSum(pointVO.getSeatSum());
                vo.setName(point.getCity());
                vo.setLon(point.getLon());
                vo.setLat(point.getLat());
                cityMap.put(point.getCity(), vo);
            } else {
                //CSData 直达城市
                cityVo.setCarSum(cityVo.getCarSum() + pointVO.getCarSum());
                cityVo.setSeatSum(cityVo.getSeatSum() + pointVO.getSeatSum());
                cityMap.put(point.getCity(), cityVo);
            }
        }

        result.put("ZHData", in);
        result.put("CCDData", out);
        result.put("CSData", cityMap);
//        result.put("geoCoordMap", geoCoordMap);
        return result;
    }

    private PointVO getAirRidePointVO(AirRidePoint point) {
        PointVO pointVO = new PointVO();
        List<AirCar> carList = backService.getCarByStatusAndAirRidePointId(2,point.getId());
        Integer seatSum = 0;
        for (AirCar airCar : carList) {
            seatSum += airCar.getSeating();
        }
        pointVO.setLon(point.getLon());
        pointVO.setLat(point.getLat());
        pointVO.setName(point.getName());
        pointVO.setCarSum(carList.size());
        pointVO.setSeatSum(seatSum);
        return pointVO;
    }

}
